package com.qf.controller;

import com.qf.constant.Constant;
import com.qf.converter.MyDateConverter;
import com.qf.pojo.User;
import com.qf.responsdata.ResponseData;
import com.qf.service.UserService;
import com.qf.service.impl.UserServiceImpl;
import com.qf.utils.JsonUtils;
import com.qf.utils.MD5Utils;
import com.qf.utils.UUIDUtils;
import org.apache.commons.beanutils.BeanUtils;
import org.apache.commons.beanutils.ConvertUtils;

import javax.servlet.*;
import javax.servlet.http.*;
import javax.servlet.annotation.*;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.net.URLEncoder;
import java.util.Date;
import java.util.Map;

/**
 *前台用户的模块的后端接口地址
 */
@WebServlet("/user")
public class UserServlet extends  BaseServlet{

    /**
     * 子类的方法
     * @param request
     * @param response
     */
       /* public void add(HttpServletRequest request,HttpServletResponse response){
            System.out.println("进入add方法了") ;
        }*/

    /**
     * 异步校验用户名的方法
     * @param request 请求对象
     * @param response 响应对象
     */
    public void checkUser(HttpServletRequest request,HttpServletResponse response) throws IOException {

        //"/MavenProject_2211_war_exploded/checkUser?username="+username+""
        //1)获取username参数
        String username = request.getParameter("username");
        //System.out.println(username) ;
        //2)调用针对用户的业务接口
        UserService userService = new UserServiceImpl() ;
        ResponseData responseData = userService.checkUserByUsername(username);

        //3)ResponseData转换成json数据
        //将一个实体对象转换成json
        String jonsStr = JsonUtils.object2json(responseData);
        //解决响应的中文乱码
        //response.setContentType("text/html;charset=utf-8");
        //4)json串响应给前端
        response.getWriter().write(jonsStr);
    }

    /**
     * 用户注册功能
     * @param request  请求对象
     * @param response 响应对象
     */
    public void userRegister(HttpServletRequest request,HttpServletResponse response) throws ServletException, IOException {
        //1)解决post提交中文乱码
        // request.setCharacterEncoding("utf-8") ;
        //2)校验验证码
        //从前端获取到验证码  name="code"
        String code = request.getParameter("code");
        //从服务器端获取HttpSession会话
        HttpSession session = request.getSession();
        if(session!=null){
            //目前已经存在会话
            //从HttpSession获取存储的验证码
            String checkcode_server = (String) session.getAttribute("CHECKCODE_SERVER");
            //验证码必须是一次性验证
            session.removeAttribute("CHECKCODE_SERVER");

            if(code==null || !code.equalsIgnoreCase(checkcode_server)){
                //错误提示
                request.setAttribute("msg","验证码校验失败!");
                //请求转发到 前台注册页面中
                request.getRequestDispatcher("/jsp/message.jsp").forward(request,response);
                return;
            }
        }
        Map<String, String[]> map = null;
        User user = null;


        try {
            //3)接收前台用户注册的其他用户信息!
            //接收Map<String,String[]>
            map = request.getParameterMap();
            //封装User对象
            user = new User();

            System.out.println(user);

            //下面封装User对象数据之前,必须处理日期
            // String birthday = request.getParameter("birthday");
            //2022/12/29
            //将日期文本字符串----java.util.Date------>SimpleDateForam的pares(String dateStr) 解析--->Date
           /* SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd") ;
            Date date = sdf.parse(birthday);
            //java.util.Date--->java.sql.Date
            //java.sql.Date date2 = new java.sql.Date(date.getTime()) ;
            user.setBirthday(date) ;*/

            //使用commons-BeanUtils工具ConvertUtils转换工具有一个方法
            //public void register(Converter convet 转换器接口,Class<?> clazz)
            //注册自定义转换器
            ConvertUtils.register(new MyDateConverter(), Date.class);



            //提供一个插件工具 commons-beanUtils.jar
            //BeanUtils类有一个方法:public static void populate(Object bean, Map<String, ? extends Object> properties)
            //自动set属性
            BeanUtils.populate(user,map);  //要么它封装User数据--要用人加的日期转换器  / 要么 自己request.getParameter(name属性值)
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }

        //用户的uid---通过jdk提供UUID工具类---产生随机数字符串
        user.setUid(UUIDUtils.getId());

        //密码加密
        user.setPassword(MD5Utils.md5(user.getPassword()));
        //用户的state状态  默认0
        //用户的激活码
        user.setCode(UUIDUtils.getCode());


        //调用针对用户业务接口
        UserService userService = new UserServiceImpl() ;
        userService.addUser(user) ;

        //提示信息
        request.setAttribute("msg","注册成功");
        request.getRequestDispatcher("/jsp/message.jsp").forward(request,response);
    }

    /**
     * 用户激活功能
     * @param request 请求对象
     * @param response 响应对象
     */
    public void activeUser(HttpServletRequest request,HttpServletResponse response) throws ServletException, IOException {
        //https://mail.163.com/MavenProject_2211_war_exploded/user?methodName=activeUser&code=780FED986F27426A95CDD29309D09903
        //1)获取激活的路径的上的参数
        String code = request.getParameter("code");
        //2)调用用户的业务接口UserService
        UserService userService = new UserServiceImpl() ;
        userService.activeUser(code) ;
        //3)request域设置信息
        request.setAttribute("msg","用户激活成功,请<a href='"+request.getContextPath()+"/jsp/login.jsp'>登录</a>");
        //4)请求转发到消息提示页
        request.getRequestDispatcher("/jsp/message.jsp").forward(request,response);

    }

    /**
     * 前台用户的登录功能
     * @param request  请求对象
     * @param response 响应对象
     */
    public void userLogin(HttpServletRequest request,HttpServletResponse response) throws IOException, ServletException {
        //1)校验前台输入的验证码
        //name="code"
        String code = request.getParameter("code");
        //2)获取HttpSession
        HttpSession session = request.getSession();
        if(session!=null){
            //存储在Httpsession会话
            //获取服务器端都存储的验证码
            String check_code_sever= (String) session.getAttribute("CHECKCODE_SERVER");
            //一次性验证
            session.removeAttribute("CHECKCODE_SERVER");

            if(code==null || !code.equalsIgnoreCase(check_code_sever)){
                //设置错误提示
                request.setAttribute("msg","登录验证码校验失败") ;
                request.getRequestDispatcher("/jsp/login.jsp").forward(request,response);
                return;
            }
        }

        //4)上验证码校验通过
        //接收用户名和密码参数
        String username = request.getParameter("username");
        String password = request.getParameter("password");
        //密码加密
        password = MD5Utils.md5(password) ;
        //5)调用用户的业务接口
        UserService userService = new UserServiceImpl() ;
        User user = userService.userLogin(username, password);
        if(user==null){
            //没找到
            //错误提示
            request.setAttribute("msg","用户名或者密码输入错误!");
            request.getRequestDispatcher("/jsp/login.jsp").forward(request,response) ;
            return;
        }

        //user是存在的
        if(user.getState()!= Constant.USER_STATE){
            //错误 提示
            request.setAttribute("msg","用户未激活") ;
            request.getRequestDispatcher("/jsp/login.jsp").forward(request,response);
            return;
        }

        //判断用户是否勾选了自动登录
        //如果勾选了,将用户名和密码 添加到cookie中
        // cookie的名称 "autoUser","昵称=密码"

        //获取前台用户勾选的值  name="auto_user"
        String auto_user = request.getParameter("auto_user");
        //auto_user和复选框的value的默认值进行比较
        if(!"AutoUser".equals(auto_user)){
            //没有勾选---不存储cookie
            //创建Cookie
            Cookie cookie  = new Cookie("autoUser","") ;
            //有效期
            cookie.setMaxAge(0); //会自动删除cookie
            //携带给浏览器
            response.addCookie(cookie) ;

        }else{
            //勾选了--->给浏览器存储cookie
            //创建Cookie
            //cookie内容约定一个格式:将用户名和密码通过=拼接起来
            //jdk提供一个工具:URLEncoder--->public static String encode(String s,String enc)
            //将指定的字符串,使用指定的字符集加密
            String content = user.getUsername() +"="+user.getPassword() ;
            content = URLEncoder.encode(content,"utf-8") ;


            Cookie cookie = new Cookie("autoUser",content) ;
            //设置有效期,设置一个月
            cookie.setMaxAge(60*60*24*30);
            //将cookie对象携带给浏览器
            response.addCookie(cookie);

        }


        //用户激活状态1
        //将用户的新存储在HttpSession  服务端
        session.setAttribute("user",user) ;
        //重定向 到jsp/index.jsp 前台主页
        response.sendRedirect(request.getContextPath()+"/");

    }

    /**
     * 前台用户退出功能
     * @param request  请求对象
     * @param response 响应对象
     */
    public void userLogout(HttpServletRequest request,HttpServletResponse response) throws IOException {

        //通过请求对象获取HttpSession
        HttpSession session = request.getSession();
        if(session!=null){
            //存在会话中
            // public void invalidate();让session会话失效,取消对任何数据的绑定
            session.invalidate();
            //重定向到首页
            response.sendRedirect(request.getContextPath()+"/jsp/index.jsp");
        }

    }
}
